package com.chenyuxin.ilp.service.file.Impl;

import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.SaveFormat;
import com.aspose.cells.Workbook;
import com.aspose.slides.PdfOptions;
import com.aspose.slides.Presentation;
import com.aspose.words.Document;
import com.aspose.words.PdfCompliance;
import com.aspose.words.PdfTextCompression;
import com.chenyuxin.ilp.exception.BaseException;
import com.chenyuxin.ilp.mapper.file.FilePreviewMapper;
import com.chenyuxin.ilp.model.entity.file.FilePreview;
import com.chenyuxin.ilp.model.enums.exception.ExceptionEnums;
import com.chenyuxin.ilp.model.vo.file.FileConvertTask;
import com.chenyuxin.ilp.service.file.ConvertFileService;
import com.chenyuxin.ilp.util.AsposeRegister;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.UUID;

@Service
@Slf4j
public class ConvertFileServiceImpl implements ConvertFileService {

    @Value("${minio.bucket.files}")
    private String bucket;
    @Autowired
    private FilePreviewMapper filePreviewMapper;
    @Autowired
    private MinioServiceImpl minioService;
    // word转PDF
    public void generateWordPreviewFile(FileConvertTask message) {
        try {
            AsposeRegister.registerWord_v_22_5();
        } catch (Exception e) {
            log.error("获取word转pdf的vip失败");
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }

        String randomName = UUID.randomUUID().toString().replace("-", "");
        String filename = randomName + message.getExtension();
        String pdfName = randomName + ".pdf";
        String localFilePathName = "/Users/chenyuxin/" + filename;
        String pdfFilepathName = "/Users/chenyuxin/" + pdfName;

        saveFile(message.getFileBytes(), localFilePathName);

        try {
            Document doc = new Document(localFilePathName);
            doc.save(pdfFilepathName);
        } catch (Exception e) {
            log.error("文件类型转换失败,errMessage:{},localFilePathName:{}", e.getMessage(), localFilePathName);
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }

        // 上传文件到minio
        uploadFile(pdfFilepathName, pdfName, message);
        // 将预览文件信息插入到file_preview表
        insertFilePreview(message, pdfName);
        // 删除本地文件
        deleteLocalFiles(localFilePathName, pdfFilepathName);
        System.out.println("PDF saved successfully.");
    }

    // Excel转PDF
    @Override
    public void generateExcelPreviewFile(FileConvertTask message) {
        try {
            AsposeRegister.registerExcel_v_22_6();
        } catch (Exception e) {
            log.error("获取excel转pdf的vip失败");
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }

        String randomName = UUID.randomUUID().toString().replace("-", "");
        String filename = randomName + message.getExtension();
        String pdfName = randomName + ".pdf";
        String localFilePathName = "/Users/chenyuxin/" + filename;
        String pdfFilepathName = "/Users/chenyuxin/" + pdfName;

        saveFile(message.getFileBytes(), localFilePathName);

        try {
            Workbook workbook = new Workbook(localFilePathName);
            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
            pdfSaveOptions.setOnePagePerSheet(true);
            workbook.save(pdfFilepathName, SaveFormat.PDF);
        } catch (Exception e) {
            log.error("文件类型转换失败,errMessage:{},localFilePathName:{}", e.getMessage(), localFilePathName);
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }
        // 上传文件到minio
        uploadFile(pdfFilepathName, pdfName, message);
        // 将预览文件信息插入到file_preview表
        insertFilePreview(message, pdfName);
        // 删除本地文件
        deleteLocalFiles(localFilePathName, pdfFilepathName);
        System.out.println("PDF saved successfully.");
    }

    // ppt转PDF
    @Override
    public void generatePPTPreviewFile(FileConvertTask message) {
        try {
            AsposeRegister.registerPPT_v_21_10();
        } catch (Exception e) {
            log.error("获取ppt转pdf的vip失败");
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }

        String randomName = UUID.randomUUID().toString().replace("-", "");
        String filename = randomName + message.getExtension();
        String pdfName = randomName + ".pdf";
        String localFilePathName = "/Users/chenyuxin/" + filename;
        String pdfFilepathName = "/Users/chenyuxin/" + pdfName;

        saveFile(message.getFileBytes(), localFilePathName);

        try {
            Presentation presentation = new Presentation(localFilePathName);
            PdfOptions pdfOptions = new PdfOptions();
            pdfOptions.setJpegQuality((byte) 90);
            pdfOptions.setSaveMetafilesAsPng(true);
            pdfOptions.setTextCompression(PdfTextCompression.FLATE);
            pdfOptions.setCompliance(PdfCompliance.PDF_A_1_B);
            presentation.save(pdfFilepathName, com.aspose.slides.SaveFormat.Pdf);
        } catch (Exception e) {
            log.error("文件类型转换失败,errMessage:{},localFilePathName:{}", e.getMessage(), localFilePathName);
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }

        // 上传文件到minio
        uploadFile(pdfFilepathName, pdfName, message);
        // 将预览文件信息插入到file_preview表
        insertFilePreview(message, pdfName);
        // 删除本地文件
        deleteLocalFiles(localFilePathName, pdfFilepathName);
        System.out.println("PDF saved successfully.");
    }
    // 抽取公共的文件保存方法
    private void saveFile(byte[] fileBytes, String localFilePath) {
        try {
            Files.write(Paths.get(localFilePath), fileBytes);
        } catch (IOException e) {
            log.error("将消息字节码转文件失败,errMessage:{},localFilePathName:{}", e.getMessage(), localFilePath);
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }
    }

    // 抽取公共的上传文件方法
    private void uploadFile(String localFilePath, String pdfName, FileConvertTask message) {
        String objectName = "/" + message.getUserId() + "/preview/" + pdfName;
        Boolean upload = minioService.upload(localFilePath, bucket, objectName, ".pdf");
        if (!upload) {
            log.error("文件上传到minio失败,objectName:{}", objectName);
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }
    }

    // 抽取公共的数据库插入方法
    private void insertFilePreview(FileConvertTask message, String pdfName) {
        FilePreview filePreview = new FilePreview();
        filePreview.setInitialFileId(message.getInitialFileId());
        filePreview.setPreviewFileName(pdfName);
        filePreview.setCreateTime(LocalDateTime.now());
        filePreviewMapper.insert(filePreview);
    }

    // 抽取公共的删除文件方法
    private void deleteLocalFiles(String localFilePath, String pdfFilepathName) {
        try {
            Files.delete(Paths.get(localFilePath));
            Files.delete(Paths.get(pdfFilepathName));
        } catch (IOException e) {
            log.error("删除本地文件失败,errMessage:{},localFilePathName:{},pdfFilepathName:{}", e.getMessage(), localFilePath, pdfFilepathName);
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }
    }


}
